package main.interaction
{
	import com.baseoneonline.flash.utils.logger.Logger;
	
	import flash.events.EventDispatcher;
	
	import gs.TweenLite;
	
	import main.Conf;
	import main.Scene3D;
	import main.util.Util;
	
	[Event(type="main.StateEvent", name="stateChanged")]
	[Event(type="main.StateEvent", name="mouseOver")]
	[Event(type="main.StateEvent", name="mouseOut")]
	[Event(type="main.StateEvent", name="mouseUp")]
	[Event(type="main.StateEvent", name="regionOver")]
	[Event(type="main.StateEvent", name="regionOut")]
	[Event(type="main.StateEvent", name="regionUp")]
	public class StateManager extends EventDispatcher
	{
		
		private var currentState:State;
		
		private var interactiveObjects:Array = [];
		private var interactiveRegions:Array = [];
		
		private var states:Object = {};
		
		private var scene:Scene3D;
		private var regions:ScreenRegions;
		
		private var interactivityDelay:Number = Conf.STATECHANGE_INTERACTIVITY_DELAY;
		
		public function StateManager(xml:XML, scene:Scene3D, regions:ScreenRegions) {
			this.regions = regions;
			this.scene = scene;
			parseStates(xml);
			changeState(Util.exists(xml.@initialState), true);
		}
		
		private function parseStates(xml:XML):void {
			for each (var x:XML in xml.state) {
				var state:State = State.fromXML(x);
				states[state.name] = state;
			}
			
			for each(var s:State in states) {
				for each(var ob:InteractiveObject in s.interactiveObjects) {
					ob.object = scene.findObject(ob.objectName);
					ob.addEventListener(StateEvent.MOUSE_OVER, onInteractiveObjectOver);
					ob.addEventListener(StateEvent.MOUSE_OUT, onInteractiveObjectOut);
					ob.addEventListener(StateEvent.MOUSE_UP, onInteractiveObjectUp);
				}
				for each(var ir:InteractiveRegion in s.interactiveRegions) {
					ir.region = regions.getRegion(ir.regionName);
					ir.addEventListener(StateEvent.REGION_OVER, onRegionOver);
					ir.addEventListener(StateEvent.REGION_OUT, onRegionOut);
					ir.addEventListener(StateEvent.REGION_UP, onRegionUp);
				}
			}
			
		}
		
		private function onRegionOver(e:StateEvent):void {
			bubbleEvent(e);
		}
		
		private function onRegionOut(e:StateEvent):void {
			bubbleEvent(e);
		}
		
		private function onRegionUp(e:StateEvent):void {
			bubbleEvent(e);
			if (e.interactiveRegion.targetState) {
				changeState(e.interactiveRegion.targetState);
			}
		}
		
		private function onInteractiveObjectOver(e:StateEvent):void {
			bubbleEvent(e);
		}

		private function onInteractiveObjectOut(e:StateEvent):void {
			bubbleEvent(e);
		}

		private function onInteractiveObjectUp(e:StateEvent):void {
			if (e.interactiveObject.targetState) {
				changeState(e.interactiveObject.targetState);
			}
			bubbleEvent(e);
		}
		
		private function bubbleEvent(e:StateEvent):void {
			var ev:StateEvent = new StateEvent(e.type);
			ev.interactiveObject = e.interactiveObject;
			ev.interactiveRegion = e.interactiveRegion;
			ev.state = e.state;
			dispatchEvent(ev);
		}

		public function changeState(stateName:String, immediate:Boolean=false):void {
			Logger.debug(this, "Change state: "+stateName);
			var state:State = states[stateName];
			if (!state) throw new Error("State does not exist: "+stateName);
			currentState = state;
			
			var iob:InteractiveObject;
			var ir:InteractiveRegion;
 			// Disable old interactiveObjects
 			for each(iob in interactiveObjects) {
 				iob.enabled = false;
 			}
 			for each(ir in interactiveRegions) {
 				ir.enabled = false;
 			}
 			interactiveRegions = [];
 			interactiveObjects = [];
			scene.changeCamera(currentState.camera, immediate);
			TweenLite.delayedCall(interactivityDelay, enableInteractives);
		}
		
		private function enableInteractives():void {
 			// Enable new interactiveObjects
			var iob:InteractiveObject;
			var ir:InteractiveRegion;
 			for each(iob in currentState.interactiveObjects) {
 				iob.enabled = true;
 				interactiveObjects.push(iob);
 			}
 			
 			for each(ir in currentState.interactiveRegions) {
 				ir.enabled = true;
 				interactiveRegions.push(ir);
 			}
			regions.refresh();
			
			
			var ev:StateEvent = new StateEvent(StateEvent.STATE_CHANGED);
			dispatchEvent(ev);
			
		}
		
		
		
		
		
	}
}
//	import main.Scene3D;
//	import away3d.core.base.Object3D;
//	import away3d.events.MouseEvent3D;
//	import main.Util;
//	import main.StateManager;
//	import flash.filters.GlowFilter;
//	import flash.filters.BlurFilter;
//	
//
//class Interaction {
//	
//	public var xml:XML;
//	private var scene:Scene3D;
//	private var object:Object3D;
//	private var manager:StateManager;
//	
//	public function Interaction(xml:XML, scene:Scene3D, manager:StateManager) {
//		this.xml = xml;
//		this.scene = scene;
//		this.manager = manager;
//		object = scene.findObject(Util.exists(xml.@object));
//		object.addOnMouseUp(onMouseUp);
//		object.addOnMouseOver(onMouseOver);
//		object.addOnMouseOut(onMouseOut);
//		object.useHandCursor = true;
//	}
//	
//	public function destroy():void {
//		object.removeOnMouseUp(onMouseUp);
//		object.removeOnMouseOver(onMouseOver);
//		object.removeOnMouseOut(onMouseOut);
//		object.useHandCursor = false;
//		xml = null;
//		scene = null;
//		object = null;
//		manager = null;
//	}
//	
//	private function onMouseOver(e:MouseEvent3D):void {
//		object.alpha = .5;
//		
//	}
//	
//	private function onMouseOut(e:MouseEvent3D):void {
//		
//	}
//
//	private function onMouseUp(e:MouseEvent3D):void {
//		if (xml.@targetState) {
//			manager.changeState(xml.@targetState);
//		}
//	}
//	
//	
//
//}